/**
 * Create in 2012-7-29.
 */
package kit4j.tests.jdk.swing.dnd.table;

import java.awt.Component;
import java.awt.Container;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.io.Serializable;

import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JTable;

import kit4j.view.cs.swing.dnd.ComponentMoveTransferHandler;
import kit4j.view.cs.swing.dnd.LocalObjectRefTransferable;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 
 * @author MiniKnife
 * 
 */
public class JTableTransferHandler extends ComponentMoveTransferHandler {

	private static final long serialVersionUID = 1L;

	private static final Logger log = LoggerFactory.getLogger(JTableTransferHandler.class);

	private JTable table;

	public JTableTransferHandler(JTable table) {
		super(table);
		this.table = table;
	}

	@Override
	public int getSourceActions(JComponent source) {
		return MOVE | COPY | LINK;
	}

	@Override
	protected Transferable createTransferable(JComponent source) {
		int selectedRow = table.getSelectedRow();
		int selectedColumn = table.getSelectedColumn();
		int rowCount = table.getRowCount();
		int columnCount = table.getColumnCount();
		
		if(selectedRow >= 0 && selectedRow < rowCount && selectedColumn >= 0 && selectedColumn < columnCount) {
			Object value = table.getValueAt(selectedRow, selectedColumn);
			
			if(value != null && (value instanceof Serializable)) {
				return new LocalObjectRefTransferable((Serializable) value);
			}
		}

		return null;
	}

	@Override
	public boolean canImport(TransferSupport support) {
		JTable.DropLocation location = (JTable.DropLocation) support.getDropLocation();
		if ((table.getDragEnabled() || true) && !location.isInsertColumn() && !location.isInsertRow()) {
			int row = location.getRow();
			int column = location.getColumn();
			int rowCount = table.getRowCount();
			int columnCount = table.getColumnCount();
			return row >= 0 && row < rowCount && column >= 0 && column < columnCount
					&& null == table.getValueAt(row, column) && super.canImport(support);
		}

		return false;
	}

	@Override
	public boolean importData(TransferSupport support) {
		Transferable tf = support.getTransferable();
		JTable.DropLocation location = (JTable.DropLocation) support.getDropLocation();
		int row = location.getRow();
		int column = location.getColumn();

		try {
			Component comp = (Component) tf.getTransferData(new DataFlavor(DataFlavor.javaJVMLocalObjectMimeType
					+ ";class=" + Component.class.getCanonicalName()));
			Container oldContainer = comp.getParent();

			if (comp instanceof JButton) {
				log.debug("is JButton!");
			}

			table.setValueAt(comp, row, column);

			log.info("Drop component at: row={}, column={}.", row, column);

			// 从原容器中移除组件并刷新原容器界面
			if (oldContainer != null && oldContainer != table) {
				oldContainer.remove(comp);
				validateAndRepaintContainer(oldContainer);
			}

			log.debug("imported!");

			return true;
		} catch (Exception e) {
			return false;
		}
	}

	/**
	 * 验证并重绘指定的容器。如果指定的容器存在父容器，则直接验证并重绘父容器。
	 * 
	 * @param container
	 *            要执行操作的容器
	 */
	private void validateAndRepaintContainer(Container container) {
		Container parent = container.getParent();

		if (parent != null) {
			parent.validate();
			parent.repaint();
		} else {
			container.validate();
			container.repaint();
		}
	}

}
